package com.dragonlance;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import java.util.concurrent.Executors;

import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
import org.apache.mina.core.service.IoAcceptor;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.executor.ExecutorFilter;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;

import com.dragonlance.net.DLMessageHandler;
import com.dragonlance.net.DLProtocalCodecFactory;
import com.dragonlance.net.PackageInHandler;

public class DLServer {
	private static final int PORT = 8878;
	private static DLServer server;
	private ClientMgr clientMgr;
	private PackageInHandler pkgInHandler;
	private DLServer(){
		clientMgr = new ClientMgr();
		pkgInHandler = new PackageInHandler();
	}
	
	public static DLServer getInstance(){
		return server;
	}
	
	public ClientMgr getClientMgr(){
		return clientMgr;
	}
	
	public void start(){
		try{
			loadDLData();
			loadMapData();
			initSocketServer();
		}catch(Exception e)
		{
			System.out.println(e.getMessage()+" 启动服务器失败!");
		}
	}
	
	private void initSocketServer() throws IOException {
		IoAcceptor acceptor = new NioSocketAcceptor();  
        // 定义SLF4J 日志级别 Look: http://riddickbryant.iteye.com/blog/564330  
        LoggingFilter loggingFilter = new LoggingFilter();  
//        loggingFilter.setSessionCreatedLogLevel(LogLevel.NONE);// 一个新的session被创建时触发  
//        loggingFilter.setSessionOpenedLogLevel(LogLevel.NONE);// 一个新的session打开时触发  
//        loggingFilter.setSessionClosedLogLevel(LogLevel.NONE);// 一个session被关闭时触发  
//        loggingFilter.setMessageReceivedLogLevel(LogLevel.NONE);// 接收到数据时触发  
//        loggingFilter.setMessageSentLogLevel(LogLevel.NONE);// 数据被发送后触发  
//        loggingFilter.setSessionIdleLogLevel(LogLevel.INFO);// 一个session空闲了一定时间后触发  
//        loggingFilter.setExceptionCaughtLogLevel(LogLevel.INFO);// 当有异常抛出时触发  
  
        acceptor.getFilterChain().addLast("logger", loggingFilter);  
        // 过滤器（自定义协议）  
        acceptor.getFilterChain().addLast("codec",  
                new ProtocolCodecFilter(new DLProtocalCodecFactory(Charset.forName("UTF-8"))));  
//        acceptor.getFilterChain().addLast( "codec", new ProtocolCodecFilter( new TextLineCodecFactory( Charset.forName( "UTF-8" ))));
        // 设置数据将被读取的缓冲区大小  
        acceptor.getSessionConfig().setReadBufferSize(3000);  
        // 10秒内没有读写就设置为空闲通道  
        acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);  
  
        // 连接池设置  
        // get a reference to the filter chain from the acceptor  
        DefaultIoFilterChainBuilder filterChainBuilder = acceptor.getFilterChain();  
        filterChainBuilder.addLast("threadPool", new ExecutorFilter(Executors.newCachedThreadPool()));  
  
        acceptor.setHandler(new DLMessageHandler());  
        acceptor.bind(new InetSocketAddress(PORT));  
	}

	private void loadMapData() {
		
	}

	private void loadDLData() {
		
	}

	public static void main(String[] args) throws IOException
	{
		server = new DLServer();
		server.start();
        System.out.println("Start server is listenig at port " + PORT); 
	}

	public PackageInHandler getPkgInHandler() {
		return pkgInHandler;
	}
}
